#include <stdio.h>
#include <stdlib.h>
#include "header.h"
#include "serveur.h"
#include "requetes.h"
#include <string.h>

int typeRequete(char* requete)
{
    // put
    if ( !strncmp( requete, "000" , 3 ) )	
        return 0;
    // push
    if ( !strncmp( requete, "001" , 3 ) )	
        return 1;
    // pull
    if ( !strncmp( requete, "010" , 3 ) )	
        return 2;


    if ( !strncmp( requete, "011" , 3 ) )	
        return 3;
    if ( !strncmp( requete, "100" , 3 ) )	
        return 4;
    if ( !strncmp( requete, "101" , 3 ) )	
        return 5;
    if ( !strncmp( requete, "110" , 3 ) )	
        return 6;
    if ( !strncmp( requete, "111" , 3 ) )	
        return 7;
    return -1;
}

int traitementRequetes(SOCKET service){
    char tampon[TAILLE_BUFFER];
    char requete[4];
    char * fichier;
    int lu,  err, taillenom;
    long taille;
    //attente requete
    if( 0 > (lu = lireBinaire(service, tampon, TAILLE_BUFFER)) )
    {
        puts("erreur traitement");
        return -1;
    }
    if (4 > lu){

        puts("protocole non supporté");
        return -1;
    }
    // recuperation de la requete
    strncpy(requete, tampon, 3);
    requete[3] ='\0';
    puts(requete);

    switch(typeRequete(requete)){
        case 0 :
            puts("requete put");
            taillenom = lu-3-sizeof(taille);
            printf("%d = %d +%lu +%d", lu, 3, sizeof(taille), taillenom); 
            printf("taillenom : %d", taillenom);
            //recuperation de la taille du fichier
            memcpy(&taille, tampon+3, sizeof(taille));
            printf("taille fichier : %ld\n",taille);
            // recuperation du nom de fichier a transferer
            if (NULL == (fichier = malloc((taillenom+1))))
            {
                puts("erreur de recuperation du nom");
                return -10;
            }
            strncpy(fichier , tampon+3+sizeof(taille),taillenom);
            fichier[lu-sizeof(taille)-3] = '\0';
            puts(fichier);
            printf("reception du fichier %s\n", fichier);

            err = traitementPut(service, fichier, taille);
            free(fichier);
            if ( 0 != err){
                return -20;
            }

            break;
        case 1 :
            puts("requete push");
            break;
        case 2 :
            puts("requete pull");
            break;

        default :
            puts("requete inconnue !");
            return -2;

    }
    return 0;
}


int traitementPut(SOCKET service ,const char* fichier, long size){
    char tampon[TAILLE_BUFFER];
    long lu, ecrit, total=0;
    FILE * descFich;
    long taille = size;
    puts("traitement");
    printf("ouverture du fichier %s\n", fichier);
    if (NULL == ( descFich = fopen(fichier, "wb"))){
        perror(fichier);
        return -1;
    }
    while(0 < taille){
        printf("reception de %ld Octets", total);
        printf("%ld octets restant\n", taille);
        //recuperation du morceau de fichier
        if(taille > TAILLE_BUFFER){
            total = TAILLE_BUFFER;
        }else{
            total = taille;
        }

        if( 0 > (lu = lireBinaire(service, tampon, total)) )
        {
            puts("erreur traitement");
            return -2;
        }
        if(1 !=( ecrit = fwrite(tampon, lu, 1, descFich) ) ) {
            printf("erreur d'ecriture du fichier %ld Octets x %ld\n" , lu, ecrit);
            fclose(descFich);
            return -3;
        }
        taille-=lu;

    }
    if ( fclose(descFich)){
        perror(fichier);
        return -10;
    }

    return 0;
}



int envoyerPut(SOCKET service, const char* fichier){
    char tampon[TAILLE_BUFFER];
    long taille , lu, ecrit, total = 0 ; 
    FILE * descFich;
    // int lu, ecrit, total;
    puts("requetes()");
    puts(fichier);

    if (NULL == ( descFich = fopen(fichier, "rb"))){
        perror(fichier);
        return -1;
    }

    if (0 != fseek (descFich, 0, SEEK_END)){
        perror(fichier);
        fclose(descFich);
        return -2;
    }
    if( -1 == (taille=    ftell(descFich))){
        perror(fichier);
        fclose(descFich);
        return -3;
    }
    if (0 != fseek (descFich, 0,SEEK_SET)){
        perror(fichier);
        fclose(descFich);
        return -2;
    }
    printf("taille : %ld\n", taille);
    strncpy(tampon, "000", 3);
    memcpy(tampon+3,  &taille, sizeof(taille));
    memcpy(tampon+3+sizeof(taille), fichier, strlen(fichier) );
    ecrireBinaire(service, tampon, 3+sizeof(taille)+strlen(fichier));

    //copie du fichier
    getchar();


    while (taille >0 ){
        if( taille > TAILLE_BUFFER){
            total = TAILLE_BUFFER;
        }
        else{
            total = taille;
        }
        if(1!=( lu = fread(tampon, total, 1, descFich))){
            perror(fichier);
            return -4; 
        }

        if( 0== (ecrit = ecrireBinaire(service, tampon, total))){
            perror(fichier);
            return -5;
        }
        taille-= ecrit;
        printf("%ld octets restant\n", taille);
    }
    if ( fclose(descFich)){
        perror(fichier);
        return -10;
    }

    return 0;
}
